<?php

namespace LRP;

use LRP\Contract\TubeFactoryInterface;
use LRP\Contract\TubeInterface;
use LRP\Tube\RedisTube;

/**
 * Class TubeFactory
 *
 * PHP Version > 7.0
 *
 * @package LRP
 * @author  Jon
 * @link    https://gitee.com/joncc/long-running-processor
 */
class TubeFactory implements TubeFactoryInterface
{
    const AUTODETECT = 0;
    const REDIS = 1;
    const ZEROMQ = 2;
    const PHEANSTALK = 3;
    const KAFKA = 4;
    const RABBITMQ = 5;

    private $host;
    private $port;
    private $timeout;

    /**
     * @var int
     */
    private $implementation;

    /**
     * TubeFactory constructor.
     *
     * @param string $host
     * @param int $port
     * @param int $timeout
     * @param int $implementation
     */
    public function __construct(string $host, int $port, int $timeout = 0, $implementation = self::AUTODETECT)
    {
        $this->host = $host;
        $this->port = $port;
        $this->timeout = $timeout;
        $this->setImplementation($implementation);
    }

    /**
     * @param int $implementation
     */
    public function setImplementation(int $implementation)
    {
        if ($implementation === self::AUTODETECT) {
            // Prefer redis
            if (extension_loaded('redis')) {
                $this->implementation = self::REDIS;
                return;
            }
        } else {
            $this->implementation = $implementation;
        }
    }

    /**
     * @return int
     */
    public function getImplementation(): int
    {
        return $this->implementation;
    }

    /**
     * @return TubeInterface
     * @throws \Exception
     */
    public function create(): TubeInterface
    {
        switch ($this->implementation) {
            case self::REDIS:
                return $this->createRedisTube();
            default:
                throw new \RuntimeException("Unknown implementation");
        }
    }

    /**
     * @return TubeInterface
     * @throws \Exception
     */
    private function createRedisTube(): TubeInterface
    {
        return new RedisTube($this->host, $this->port, $this->timeout);
    }
}
